<?php
declare(strict_types=1);

namespace ServerApp\lib\server\udp;

use ServerApp\lib\config\LogConfig;
use ServerApp\lib\memory\Chan;
use ServerApp\lib\process\SProcess;
use ServerApp\lib\util\ServerHelper;
use swoole_server;

/**
 *
 */
class Udp{
    const SPLIT = "\e";

    private $pid;

    private static $instance = null;
    private function __construct()
    {
        Chan::getInstance();
        ServerHelper::init();
        LogConfig::init();

        tracker(D, "start");

        (new SProcess(function(){
            (new SProcess(function(){
                $server = new swoole_server("0.0.0.0", PORT, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
                $server->on('Packet', function(swoole_server $server, $data, $clientInfo) {
                    unset($server);
                    unset($clientInfo);
                    Chan::getInstance()->push($data);
                });
                $server->start();
            }))->start();

            $this->createProcess();

            $this->writePid();

            SProcess::signal(SIGCHLD, function () {
                for(;;){
                    $ret = SProcess::wait();
                    if ($ret) {
                        tracker(D, $ret['pid']);
                        if ($this->pid === $ret['pid']){
                            $this->createProcess();
                            $this->writePid();
                        }
                    }
                }
            });
        }))->start();
    }

    private function writePid(){
        $content = $this->pid;
        $s = explode('\\', __CLASS__);
        file_put_contents(ServerHelper::getInstance()->getPidPath() . end($s) . __LINE__ . ".pid", $content);
    }

    public static function getFtokKey($port){
        $file_path = "/home/a_$port";
        if (!is_file($file_path)) {
            file_put_contents($file_path, "");
        }
        return ftok($file_path, '1');
    }

    private function createProcess() {
        $this->pid = (new SProcess(function(){
            new Task();
        }))->start();
    }

    public static function getInstance(){
        if (self::$instance === null) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}

//        $server->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
//        var_dump($clientInfo);